#pragma once

#include "genericproperty.h"
#include <osg/Vec3>
#include <osg/Vec3d>
#include <osg/Vec4>
#include <osg/Vec4d>
#include <osg/Vec2>
#include <osg/Vec2d>
#include <QStringList>

namespace VrDataCore
{
	template<typename T>
	class VRDATACORE_EXPORT Vec2fProperty : public GenericProperty<T,osg::Vec2f>
	{
	public:
		typedef GenericProperty<T, osg::Vec2f> BaseClass;
		typedef BaseClass::SetFun Vec2fPropertySetFun;
		typedef BaseClass::GetFun Vec2fPropertyGetFun;

		Vec2fProperty(const QString& datatype,const QString& name, const std::string& label,
			T* obj,Vec2fPropertySetFun set, Vec2fPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(osg::Vec2f vec)
		{
			GenericProperty<T,osg::Vec2f>::setValue(vec);
		}

		virtual bool fromString(const QString& value)
		{
			QStringList list = value.split(" ",QString::SkipEmptyParts);
			osg::Vec2f newvalue(0.0f,0.0f);
			if(list.size()>1)
				newvalue.set(list.at(0).toFloat(),list.at(1).toFloat());
			setValue(newvalue);
			return true;
		}

		virtual const QString toQString() const
		{
			osg::Vec2f value = GenericProperty<T,osg::Vec2f>::getValue();
			QString returnvalue = QString::number(value.x())+ " "+ QString::number(value.y());
			return returnvalue;
		}
	protected:
		virtual ~Vec2fProperty() { }
	};
	//--------------------------------------------------------------------------------------------------
	template<typename T>
	class VRDATACORE_EXPORT Vec2dProperty : public GenericProperty<T,osg::Vec2d>
	{
	public:
		typedef GenericProperty<T, osg::Vec2d> BaseClass;
		typedef BaseClass::SetFun Vec2dPropertySetFun;
		typedef BaseClass::GetFun Vec2dPropertyGetFun;

		Vec2dProperty(const QString& datatype,const QString& name, const QString& label,
			T* obj,Vec2dPropertySetFun set, Vec2dPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(osg::Vec2d vec)
		{
			GenericProperty<T,osg::Vec2d>::setValue(vec);
		}

		virtual bool fromString(const QString& value)
		{
			QStringList list = value.split(" ",QString::SkipEmptyParts);
			osg::Vec2d newvalue(0.0,0.0);
			if(list.size()>1)
				newvalue.set(list.at(0).toDouble(),list.at(1).toDouble());
			setValue(newvalue);
			return true;
		}

		virtual const QString toQString() const
		{
			osg::Vec2d value = GenericProperty<T,osg::Vec2d>::getValue();
			QString returnvalue = QString::number(value.x())+ " "+ QString::number(value.y());
			return returnvalue;
		}
	protected:
		virtual ~Vec2dProperty() { }
	};
	//--------------------------------------------------------------------------------------------------
	template<typename T>
	class VRDATACORE_EXPORT Vec3fProperty : public GenericProperty<T,osg::Vec3f>
	{
	public:
		typedef GenericProperty<T, osg::Vec3f> BaseClass;
		typedef BaseClass::SetFun Vec3fPropertySetFun;
		typedef BaseClass::GetFun Vec3fPropertyGetFun;

		Vec3fProperty(const QString& datatype,const QString& name, const std::string& label,
			T* obj,Vec3fPropertySetFun set, Vec3fPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(osg::Vec3f vec)
		{
			GenericProperty<T,osg::Vec3f>::setValue(vec);
		}

		virtual bool fromString(const QString& value)
		{
			QStringList list = value.split(" ",QString::SkipEmptyParts);
			osg::Vec3f newvalue(0.0f,0.0f,0.0f);
			if(list.size()>2)
				newvalue.set(list.at(0).toFloat(),list.at(1).toFloat(),list.at(2).toFloat());
			setValue(newvalue);
			return true;
		}

		virtual const QString toQString() const
		{
			osg::Vec3f value = GenericProperty<T,osg::Vec3f>::getValue();
			QString returnvalue = QString::number(value.x()) + " "+ QString::number(value.y()) + " "
				+ QString::number(value.z());
			return returnvalue;
		}
	protected:
		virtual ~Vec3fProperty() { }
	};
	//--------------------------------------------------------------------------------------------------
	template<typename T>
	class VRDATACORE_EXPORT Vec3fListProperty : public GenericProperty<T,QList<osg::Vec3f>>
	{
	public:
		typedef GenericProperty<T,QList<osg::Vec3f>> BaseClass;
		typedef BaseClass::SetFun Vec3fListPropertySetFun;
		typedef BaseClass::GetFun Vec3fListPropertyGetFun;

		Vec3fListProperty(const QString& datatype,const QString& name, const std::string& label,
			T* obj,Vec3fListPropertySetFun set, Vec3fListPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(const QList<osg::Vec3f>& vec)
		{
			GenericProperty<T,QList<osg::Vec3f>>::setValue(vec);
		}

		virtual bool fromString(const QString& value)
		{
			QList<osg::Vec3f> listvalue;
			QStringList list = value.split(",",QString::SkipEmptyParts);
			for(int i=0;i<list.size();++i)
			{
				QStringList poslist = list.at(i).split(" ",QString::SkipEmptyParts);
				osg::Vec3f newvalue;
				if(poslist.size()>2)
					newvalue.set(poslist.at(0).toFloat(),poslist.at(1).toFloat(),poslist.at(2).toFloat());
				listvalue.push_back(newvalue);
			}
			setValue(listvalue);
			return true;
		}

		virtual const QString toQString() const
		{
			QString returnvalue = "";
			QList<osg::Vec3f> listvalue = GenericProperty<T,QList<osg::Vec3f>>::getValue();
			for(int i=0;i<listvalue.size();++i)
			{
				QString posstring = QString::number(listvalue.at(i).x()) + " "+
					QString::number(listvalue.at(i).y()) + " "+QString::number(listvalue.at(i).z());
				returnvalue = returnvalue +","+posstring;
			}
			return returnvalue;
		}
	protected:
		virtual ~Vec3fListProperty() { }
	};
	//--------------------------------------------------------------------------------------------------
	template<typename T>
	class VRDATACORE_EXPORT Vec3dProperty : public GenericProperty<T,osg::Vec3d>
	{
	public:
		typedef GenericProperty<T, osg::Vec3d> BaseClass;
		typedef BaseClass::GetFun Vec3dPropertyGetFun;
		typedef BaseClass::SetFun Vec3dPropertySetFun;

		Vec3dProperty(const QString& datatype,const QString& name, const QString& label,
			T* obj,Vec3dPropertySetFun set, Vec3dPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(osg::Vec3d vec)
		{
			GenericProperty<T,osg::Vec3d>::setValue(vec);
		}

		virtual bool fromString(const QString& value)
		{
			QStringList list = value.split(" ",QString::SkipEmptyParts);
			osg::Vec3d newvalue(0.0,0.0,0.0);
			if(list.size()>2)
				newvalue.set(list.at(0).toDouble(),list.at(1).toDouble(),list.at(2).toDouble());
			setValue(newvalue);
			return true;
		}

		virtual const QString toQString() const
		{
			osg::Vec3d value = GenericProperty<T,osg::Vec3d>::getValue();
			QString returnvalue = QString::number(value.x()) + " "+ QString::number(value.y()) + " "
				+ QString::number(value.z());
			return returnvalue;
		}
	protected:
		virtual ~Vec3dProperty() { }
	};
	//--------------------------------------------------------------------------------------------------
	template<typename T>
	class VRDATACORE_EXPORT Vec4fProperty : public GenericProperty<T,osg::Vec4f>
	{
	public:
		typedef GenericProperty<T, osg::Vec4f> BaseClass;
		typedef BaseClass::SetFun Vec4fPropertySetFun;
		typedef BaseClass::GetFun Vec4fPropertyGetFun;

		Vec4fProperty(const QString& datatype,const QString& name, const std::string& label,
			T* obj,Vec4fPropertySetFun set, Vec4fPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(osg::Vec4f vec)
		{
			GenericProperty<T,osg::Vec4f>::setValue(vec);
		}

		virtual bool fromString(const QString& value)
		{
			QStringList list = value.split(" ",QString::SkipEmptyParts);
			osg::Vec4f newvalue(0.0f,0.0f,0.0f,1.0f);
			if(list.size()>3)
				newvalue.set(list.at(0).toFloat(),list.at(1).toFloat(),list.at(2).toFloat(),
				list.at(3).toFloat());
			setValue(newvalue);
			return true;
		}

		virtual const QString toQString() const
		{
			osg::Vec4f value = GenericProperty<T,osg::Vec4f>::getValue();
			QString returnvalue = QString::number(value.x()) + " "+ QString::number(value.y()) + " "
				+ QString::number(value.z()) + " "+ QString::number(value.w());
			return returnvalue;
		}
	protected:
		virtual ~Vec4fProperty() { }
	};
	//--------------------------------------------------------------------------------------------------
	template<typename T>
	class VRDATACORE_EXPORT Vec4dProperty : public GenericProperty<T,osg::Vec4d>
	{
	public:
		typedef GenericProperty<T, osg::Vec4d> BaseClass;
		typedef BaseClass::GetFun Vec4dPropertyGetFun;
		typedef BaseClass::SetFun Vec4dPropertySetFun;

		Vec4dProperty(const QString& datatype,const QString& name, const QString& label,
			T* obj,Vec4dPropertySetFun set, Vec4dPropertyGetFun get,
			const QString& isshowgui,const QString& bindingguitype):
			BaseClass(datatype,name,label,obj,set,get,isshowgui,bindingguitype)
		{}

		void setValue(osg::Vec4d vec)
		{
			GenericProperty<T,osg::Vec4d>::setValue(vec);
		}

		virtual bool fromString(const QString& value)
		{
			QStringList list = value.split(" ",QString::SkipEmptyParts);
			osg::Vec4d newvalue(0.0,0.0,0.0,1.0);
			if(list.size()>3)
				newvalue.set(list.at(0).toDouble(),list.at(1).toDouble(),list.at(2).toDouble()
				,list.at(3).toDouble());
			setValue(newvalue);
			return true;
		}

		virtual const QString toQString() const
		{
			osg::Vec4d value = GenericProperty<T,osg::Vec4d>::getValue();
			QString returnvalue = QString::number(value.x()) + " "+ QString::number(value.y()) + " "
				+ QString::number(value.z()) + " " + QString::number(value.w());
			return returnvalue;
		}
	protected:
		virtual ~Vec4dProperty() { }
	};    
}